home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / sndhrdw / exidy440.c < prev    next >
C/C++ Source or Header  |  2000-04-04  |  25KB  |  1,013 lines

  1. /***************************************************************************
  2.  
  3.     Exidy 440 sound system
  4.  
  5.     Special thanks to Zonn Moore and Neil Bradley for letting me hack
  6.     their Retrocade CVSD decoder into the sound system here.
  7.  
  8. ***************************************************************************/
  9.  
  10. #include "driver.h"
  11. #include <math.h>
  12.  
  13.  
  14. #define MAKE_WAVES        0
  15. #define    SOUND_LOG        0
  16. #define    FADE_TO_ZERO    1
  17.  
  18.  
  19.  
  20. /* sample rates for each chip */
  21. #define    SAMPLE_RATE_FAST        (12979200/256)    /* FCLK */
  22. #define    SAMPLE_RATE_SLOW        (12979200/512)    /* SCLK */
  23.  
  24. /* internal caching */
  25. #define    MAX_CACHE_ENTRIES        1024                /* maximum separate samples we expect to ever see */
  26. #define    SAMPLE_BUFFER_LENGTH    1024                /* size of temporary decode buffer on the stack */
  27.  
  28. /* FIR digital filter parameters */
  29. #define    FIR_HISTORY_LENGTH        57                    /* number of FIR coefficients */
  30.  
  31. /* CVSD decoding parameters */
  32. #define    INTEGRATOR_LEAK_TC        (10e3 * 0.1e-6)
  33. #define    FILTER_DECAY_TC            ((18e3 + 3.3e3) * 0.33e-6)
  34. #define    FILTER_CHARGE_TC        (18e3 * 0.33e-6)
  35. #define    FILTER_MIN                0.0416
  36. #define    FILTER_MAX                1.0954
  37. #define    SAMPLE_GAIN                10000.0
  38.  
  39.  
  40. /* channel_data structure holds info about each 6844 DMA channel */
  41. typedef struct m6844_channel_data
  42. {
  43.     int active;
  44.     int address;
  45.     int counter;
  46.     UINT8 control;
  47.     int start_address;
  48.     int start_counter;
  49. } m6844_channel_data;
  50.  
  51.  
  52. /* channel_data structure holds info about each active sound channel */
  53. typedef struct sound_channel_data
  54. {
  55.     INT16 *base;
  56.     int offset;
  57.     int remaining;
  58. } sound_channel_data;
  59.  
  60.  
  61. /* sound_cache_entry structure contains info on each decoded sample */
  62. typedef struct sound_cache_entry
  63. {
  64.     struct sound_cache_entry *next;
  65.     int address;
  66.     int length;
  67.     int bits;
  68.     int frequency;
  69.     INT16 data[1];
  70. } sound_cache_entry;
  71.  
  72.  
  73.  
  74. /* globals */
  75. UINT8 *exidy440_m6844_data;
  76. UINT8 *exidy440_sound_banks;
  77. UINT8 *exidy440_sound_volume;
  78. UINT8 exidy440_sound_command;
  79. UINT8 exidy440_sound_command_ack;
  80.  
  81. /* local allocated storage */
  82. static INT32 *mixer_buffer_left;
  83. static INT32 *mixer_buffer_right;
  84. static sound_cache_entry *sound_cache;
  85. static sound_cache_entry *sound_cache_end;
  86. static sound_cache_entry *sound_cache_max;
  87.  
  88. /* 6844 description */
  89. static m6844_channel_data m6844_channel[4];
  90. static int m6844_priority;
  91. static int m6844_interrupt;
  92. static int m6844_chain;
  93.  
  94. /* sound interface parameters */
  95. static int sound_stream;
  96. static sound_channel_data sound_channel[4];
  97.  
  98. /* debugging */
  99. static FILE *debuglog;
  100.  
  101. /* constant channel parameters */
  102. static const int channel_frequency[4] =
  103. {
  104.     SAMPLE_RATE_FAST, SAMPLE_RATE_FAST,        /* channels 0 and 1 are run by FCLK */
  105.     SAMPLE_RATE_SLOW, SAMPLE_RATE_SLOW        /* channels 2 and 3 are run by SCLK */
  106. };
  107. static const int channel_bits[4] =
  108. {
  109.     4, 4,                                    /* channels 0 and 1 are MC3418s, 4-bit CVSD */
  110.     3, 3                                    /* channels 2 and 3 are MC3417s, 3-bit CVSD */
  111. };
  112.  
  113.  
  114. /* function prototypes */
  115. static void channel_update(int ch, INT16 **buffer, int length);
  116. static void m6844_finished(int ch);
  117. static void play_cvsd(int ch);
  118. static void stop_cvsd(int ch);
  119.  
  120. static void reset_sound_cache(void);
  121. static INT16 *add_to_sound_cache(UINT8 *input, int address, int length, int bits, int frequency);
  122. static INT16 *find_or_add_to_sound_cache(int address, int length, int bits, int frequency);
  123.  
  124. static void decode_and_filter_cvsd(UINT8 *data, int bytes, int maskbits, int frequency, INT16 *dest);
  125. static void fir_filter(INT32 *input, INT16 *output, int count);
  126.  
  127.  
  128. /* debugging */
  129. #if MAKE_WAVES
  130.  
  131. #ifdef LSB_FIRST
  132. #define intelShort(x) (x)
  133. #define intelLong(x) (x)
  134. #else
  135. #define intelShort(x) (((x) << 8) | ((x) >> 8))
  136. #define intelLong(x) ((((x) << 24) | (((unsigned long) (x)) >> 24) | (( (x) & 0x0000ff00) << 8) | (( (x) & 0x00ff0000) >> 8)))
  137. #endif
  138.  
  139. static FILE *wavfile;
  140. static int wavlength;
  141.  
  142. static void write_wav_header(int frequency);
  143. static void finish_wav_file(void);
  144.  
  145. #endif
  146.  
  147.  
  148.  
  149. /*************************************
  150.  *
  151.  *    Initialize the sound system
  152.  *
  153.  *************************************/
  154.  
  155. int exidy440_sh_start(const struct MachineSound *msound)
  156. {
  157.     const char *names[] =
  158.     {
  159.         "Exidy 440 sound left",
  160.         "Exidy 440 sound right"
  161.     };
  162.     int i, length;
  163.     int vol[2];
  164.  
  165.     /* reset the system */
  166.     exidy440_sound_command = 0;
  167.     exidy440_sound_command_ack = 1;
  168.  
  169.     /* reset the 6844 */
  170.     for (i = 0; i < 4; i++)
  171.     {
  172.         m6844_channel[i].active = 0;
  173.         m6844_channel[i].control = 0x00;
  174.     }
  175.     m6844_priority = 0x00;
  176.     m6844_interrupt = 0x00;
  177.     m6844_chain = 0x00;
  178.  
  179.     /* get stream channels */
  180.     vol[0] = MIXER(100, MIXER_PAN_LEFT);
  181.     vol[1] = MIXER(100, MIXER_PAN_RIGHT);
  182.     sound_stream = stream_init_multi(2, names, vol, SAMPLE_RATE_FAST, 0, channel_update);
  183.  
  184.     /* allocate the sample cache */
  185.     length = memory_region_length(REGION_SOUND1) * 16 + MAX_CACHE_ENTRIES * sizeof(sound_cache_entry);
  186.     sound_cache = malloc(length);
  187.     if (!sound_cache)
  188.         return 1;
  189.  
  190.     /* determine the hard end of the cache and reset */
  191.     sound_cache_max = (sound_cache_entry *)((UINT8 *)sound_cache + length);
  192.     reset_sound_cache();
  193.  
  194.     /* allocate the mixer buffer */
  195.     mixer_buffer_left = malloc(2 * SAMPLE_RATE_FAST * sizeof(INT32));
  196.     if (!mixer_buffer_left)
  197.     {
  198.         free(sound_cache);
  199.         sound_cache = NULL;
  200.         return 1;
  201.     }
  202.     mixer_buffer_right = mixer_buffer_left + SAMPLE_RATE_FAST;
  203.  
  204.     if (SOUND_LOG)
  205.         debuglog = fopen("sound.log", "w");
  206.  
  207.     return 0;
  208. }
  209.  
  210.  
  211.  
  212. /*************************************
  213.  *
  214.  *    Tear down the sound system
  215.  *
  216.  *************************************/
  217.  
  218. void exidy440_sh_stop(void)
  219. {
  220.     if (SOUND_LOG && debuglog)
  221.         fclose(debuglog);
  222.  
  223.     if (sound_cache)
  224.         free(sound_cache);
  225.     sound_cache = NULL;
  226.  
  227.     if (mixer_buffer_left)
  228.         free(mixer_buffer_left);
  229.     mixer_buffer_left = mixer_buffer_right = NULL;
  230. }
  231.  
  232.  
  233.  
  234. /*************************************
  235.  *
  236.  *    Periodic sound update
  237.  *
  238.  *************************************/
  239.  
  240. void exidy440_sh_update(void)
  241. {
  242. }
  243.  
  244.  
  245.  
  246. /*************************************
  247.  *
  248.  *    Add a bunch of samples to the mix
  249.  *
  250.  *************************************/
  251.  
  252. static void add_and_scale_samples(int ch, INT32 *dest, int samples, int volume)
  253. {
  254.     sound_channel_data *channel = &sound_channel[ch];
  255.     INT16 *srcdata;
  256.     int i;
  257.  
  258.     /* channels 2 and 3 are half-rate samples */
  259.     if (ch & 2)
  260.     {
  261.         srcdata = &channel->base[channel->offset >> 1];
  262.  
  263.         /* handle the edge case */
  264.         if (channel->offset & 1)
  265.         {
  266.             *dest++ += *srcdata++ * volume / 256;
  267.             samples--;
  268.         }
  269.  
  270.         /* copy 1 for 2 to the destination */
  271.         for (i = 0; i < samples; i += 2)
  272.         {
  273.             INT16 sample = *srcdata++ * volume / 256;
  274.             *dest++ += sample;
  275.             *dest++ += sample;
  276.         }
  277.     }
  278.  
  279.     /* channels 0 and 1 are full-rate samples */
  280.     else
  281.     {
  282.         srcdata = &channel->base[channel->offset];
  283.         for (i = 0; i < samples; i++)
  284.             *dest++ += *srcdata++ * volume / 256;
  285.     }
  286. }
  287.  
  288.  
  289.  
  290. /*************************************
  291.  *
  292.  *    Mix the result to 16 bits
  293.  *
  294.  *************************************/
  295.  
  296. static void mix_to_16(int length, INT16 *dest_left, INT16 *dest_right)
  297. {
  298.     INT32 *mixer_left = mixer_buffer_left;
  299.     INT32 *mixer_right = mixer_buffer_right;
  300.     int i, clippers = 0;
  301.  
  302.     for (i = 0; i < length; i++)
  303.     {
  304.         INT32 sample_left = *mixer_left++;
  305.         INT32 sample_right = *mixer_right++;
  306.  
  307.         if (sample_left < -32768) { sample_left = -32768; clippers++; }
  308.         else if (sample_left > 32767) { sample_left = 32767; clippers++; }
  309.         if (sample_right < -32768) { sample_right = -32768; clippers++; }
  310.         else if (sample_right > 32767) { sample_right = 32767; clippers++; }
  311.  
  312.         *dest_left++ = sample_left;
  313.         *dest_right++ = sample_right;
  314.     }
  315. }
  316.  
  317.  
  318.  
  319. /*************************************
  320.  *
  321.  *    Stream callback
  322.  *
  323.  *************************************/
  324.  
  325. static void channel_update(int ch, INT16 **buffer, int length)
  326. {
  327.     /* reset the mixer buffers */
  328.     memset(mixer_buffer_left, 0, length * sizeof(INT32));
  329.     memset(mixer_buffer_right, 0, length * sizeof(INT32));
  330.  
  331.     /* loop over channels */
  332.     for (ch = 0; ch < 4; ch++)
  333.     {
  334.         sound_channel_data *channel = &sound_channel[ch];
  335.         int samples, volume, left = length;
  336.         int effective_offset;
  337.  
  338.         /* if we're not active, bail */
  339.         if (channel->remaining <= 0)
  340.             continue;
  341.  
  342.         /* see how many samples to copy */
  343.         samples = (left > channel->remaining) ? channel->remaining : left;
  344.  
  345.         /* get a pointer to the sample data and copy to the left */
  346.         volume = exidy440_sound_volume[2 * ch + 0];
  347.         if (volume)
  348.             add_and_scale_samples(ch, mixer_buffer_left, samples, volume);
  349.  
  350.         /* get a pointer to the sample data and copy to the left */
  351.         volume = exidy440_sound_volume[2 * ch + 1];
  352.         if (volume)
  353.             add_and_scale_samples(ch, mixer_buffer_right, samples, volume);
  354.  
  355.         /* update our counters */
  356.         channel->offset += samples;
  357.         channel->remaining -= samples;
  358.         left -= samples;
  359.  
  360.         /* update the MC6844 */
  361.         effective_offset = (ch & 2) ? channel->offset / 2 : channel->offset;
  362.         m6844_channel[ch].address = m6844_channel[ch].start_address + effective_offset / 8;
  363.         m6844_channel[ch].counter = m6844_channel[ch].start_counter - effective_offset / 8;
  364.         if (m6844_channel[ch].counter <= 0)
  365.         {
  366.             if (SOUND_LOG && debuglog)
  367.                 fprintf(debuglog, "Channel %d finished\n", ch);
  368.             m6844_finished(ch);
  369.         }
  370.     }
  371.  
  372.     /* all done, time to mix it */
  373.     mix_to_16(length, buffer[0], buffer[1]);
  374. }
  375.  
  376.  
  377.  
  378. /*************************************
  379.  *
  380.  *    Sound command register
  381.  *
  382.  *************************************/
  383.  
  384. READ_HANDLER( exidy440_sound_command_r )
  385. {
  386.     /* clear the FIRQ that got us here and acknowledge the read to the main CPU */
  387.     cpu_set_irq_line(1, 1, CLEAR_LINE);
  388.     exidy440_sound_command_ack = 1;
  389.  
  390.     return exidy440_sound_command;
  391. }
  392.  
  393.  
  394.  
  395. /*************************************
  396.  *
  397.  *    Sound volume registers
  398.  *
  399.  *************************************/
  400.  
  401. WRITE_HANDLER( exidy440_sound_volume_w )
  402. {
  403.     if (SOUND_LOG && debuglog)
  404.         fprintf(debuglog, "Volume %02X=%02X\n", offset, data);
  405.  
  406.     /* update the stream */
  407.     stream_update(sound_stream, 0);
  408.  
  409.     /* set the new volume */
  410.     exidy440_sound_volume[offset] = ~data;
  411. }
  412.  
  413.  
  414.  
  415. /*************************************
  416.  *
  417.  *    Sound interrupt handling
  418.  *
  419.  *************************************/
  420.  
  421. int exidy440_sound_interrupt(void)
  422. {
  423.     cpu_set_irq_line(1, 0, ASSERT_LINE);
  424.     return 0;
  425. }
  426.  
  427.  
  428. WRITE_HANDLER( exidy440_sound_interrupt_clear_w )
  429. {
  430.     cpu_set_irq_line(1, 0, CLEAR_LINE);
  431. }
  432.  
  433.  
  434.  
  435. /*************************************
  436.  *
  437.  *    MC6844 DMA controller interface
  438.  *
  439.  *************************************/
  440.  
  441. void exidy440_m6844_update(void)
  442. {
  443.     /* update the stream */
  444.     stream_update(sound_stream, 0);
  445. }
  446.  
  447.  
  448. void m6844_finished(int ch)
  449. {
  450.     m6844_channel_data *channel = &m6844_channel[ch];
  451.  
  452.     /* mark us inactive */
  453.     channel->active = 0;
  454.  
  455.     /* set the final address and counter */
  456.     channel->counter = 0;
  457.     channel->address = channel->start_address + channel->start_counter;
  458.  
  459.     /* clear the DMA busy bit and set the DMA end bit */
  460.     channel->control &= ~0x40;
  461.     channel->control |= 0x80;
  462. }
  463.  
  464.  
  465.  
  466. /*************************************
  467.  *
  468.  *    MC6844 DMA controller I/O
  469.  *
  470.  *************************************/
  471.  
  472. READ_HANDLER( exidy440_m6844_r )
  473. {
  474.     int result = 0;
  475.  
  476.     /* first update the current state of the DMA transfers */
  477.     exidy440_m6844_update();
  478.  
  479.     /* switch off the offset we were given */
  480.     switch (offset)
  481.     {
  482.         /* upper byte of address */
  483.         case 0x00:
  484.         case 0x04:
  485.         case 0x08:
  486.         case 0x0c:
  487.             result = m6844_channel[offset / 4].address >> 8;
  488.             break;
  489.  
  490.         /* lower byte of address */
  491.         case 0x01:
  492.         case 0x05:
  493.         case 0x09:
  494.         case 0x0d:
  495.             result = m6844_channel[offset / 4].address & 0xff;
  496.             break;
  497.  
  498.         /* upper byte of counter */
  499.         case 0x02:
  500.         case 0x06:
  501.         case 0x0a:
  502.         case 0x0e:
  503.             result = m6844_channel[offset / 4].counter >> 8;
  504.             break;
  505.  
  506.         /* lower byte of counter */
  507.         case 0x03:
  508.         case 0x07:
  509.         case 0x0b:
  510.         case 0x0f:
  511.             result = m6844_channel[offset / 4].counter & 0xff;
  512.             break;
  513.  
  514.         /* channel control */
  515.         case 0x10:
  516.         case 0x11:
  517.         case 0x12:
  518.         case 0x13:
  519.             result = m6844_channel[offset - 0x10].control;
  520.  
  521.             /* a read here clears the DMA end flag */
  522.             m6844_channel[offset - 0x10].control &= ~0x80;
  523.             break;
  524.  
  525.         /* priority control */
  526.         case 0x14:
  527.             result = m6844_priority;
  528.             break;
  529.  
  530.         /* interrupt control */
  531.         case 0x15:
  532.  
  533.             /* update the global DMA end flag */
  534.             m6844_interrupt &= ~0x80;
  535.             m6844_interrupt |= (m6844_channel[0].control & 0x80) |
  536.                                (m6844_channel[1].control & 0x80) |
  537.                                (m6844_channel[2].control & 0x80) |
  538.                                (m6844_channel[3].control & 0x80);
  539.  
  540.             result = m6844_interrupt;
  541.             break;
  542.  
  543.         /* chaining control */
  544.         case 0x16:
  545.             result = m6844_chain;
  546.             break;
  547.     }
  548.  
  549.     return result;
  550. }
  551.  
  552.  
  553. WRITE_HANDLER( exidy440_m6844_w )
  554. {
  555.     int i;
  556.  
  557.     /* first update the current state of the DMA transfers */
  558.     exidy440_m6844_update();
  559.  
  560.     /* switch off the offset we were given */
  561.     switch (offset)
  562.     {
  563.         /* upper byte of address */
  564.         case 0x00:
  565.         case 0x04:
  566.         case 0x08:
  567.         case 0x0c:
  568.             m6844_channel[offset / 4].address = (m6844_channel[offset / 4].address & 0xff) | (data << 8);
  569.             break;
  570.  
  571.         /* lower byte of address */
  572.         case 0x01:
  573.         case 0x05:
  574.         case 0x09:
  575.         case 0x0d:
  576.             m6844_channel[offset / 4].address = (m6844_channel[offset / 4].address & 0xff00) | (data & 0xff);
  577.             break;
  578.  
  579.         /* upper byte of counter */
  580.         case 0x02:
  581.         case 0x06:
  582.         case 0x0a:
  583.         case 0x0e:
  584.             m6844_channel[offset / 4].counter = (m6844_channel[offset / 4].counter & 0xff) | (data << 8);
  585.             break;
  586.  
  587.         /* lower byte of counter */
  588.         case 0x03:
  589.         case 0x07:
  590.         case 0x0b:
  591.         case 0x0f:
  592.             m6844_channel[offset / 4].counter = (m6844_channel[offset / 4].counter & 0xff00) | (data & 0xff);
  593.             break;
  594.  
  595.         /* channel control */
  596.         case 0x10:
  597.         case 0x11:
  598.         case 0x12:
  599.         case 0x13:
  600.             m6844_channel[offset - 0x10].control = (m6844_channel[offset - 0x10].control & 0xc0) | (data & 0x3f);
  601.             break;
  602.  
  603.         /* priority control */
  604.         case 0x14:
  605.             m6844_priority = data;
  606.  
  607.             /* update the sound playback on each channel */
  608.             for (i = 0; i < 4; i++)
  609.             {
  610.                 /* if we're going active... */
  611.                 if (!m6844_channel[i].active && (data & (1 << i)))
  612.                 {
  613.                     /* mark us active */
  614.                     m6844_channel[i].active = 1;
  615.  
  616.                     /* set the DMA busy bit and clear the DMA end bit */
  617.                     m6844_channel[i].control |= 0x40;
  618.                     m6844_channel[i].control &= ~0x80;
  619.  
  620.                     /* set the starting address, counter, and time */
  621.                     m6844_channel[i].start_address = m6844_channel[i].address;
  622.                     m6844_channel[i].start_counter = m6844_channel[i].counter;
  623.  
  624.                     /* generate and play the sample */
  625.                     play_cvsd(i);
  626.                 }
  627.  
  628.                 /* if we're going inactive... */
  629.                 else if (m6844_channel[i].active && !(data & (1 << i)))
  630.                 {
  631.                     /* mark us inactive */
  632.                     m6844_channel[i].active = 0;
  633.  
  634.                     /* stop playing the sample */
  635.                     stop_cvsd(i);
  636.                 }
  637.             }
  638.             break;
  639.  
  640.         /* interrupt control */
  641.         case 0x15:
  642.             m6844_interrupt = (m6844_interrupt & 0x80) | (data & 0x7f);
  643.             break;
  644.  
  645.         /* chaining control */
  646.         case 0x16:
  647.             m6844_chain = data;
  648.             break;
  649.     }
  650. }
  651.  
  652.  
  653.  
  654. /*************************************
  655.  *
  656.  *    Sound cache management
  657.  *
  658.  *************************************/
  659.  
  660. void reset_sound_cache(void)
  661. {
  662.     sound_cache_end = sound_cache;
  663. }
  664.  
  665.  
  666. INT16 *add_to_sound_cache(UINT8 *input, int address, int length, int bits, int frequency)
  667. {
  668.     sound_cache_entry *current = sound_cache_end;
  669.  
  670.     /* compute where the end will be once we add this entry */
  671.     sound_cache_end = (sound_cache_entry *)((UINT8 *)current + sizeof(sound_cache_entry) + length * 16);
  672.  
  673.     /* if this will overflow the cache, reset and re-add */
  674.     if (sound_cache_end > sound_cache_max)
  675.     {
  676.         reset_sound_cache();
  677.         return add_to_sound_cache(input, address, length, bits, frequency);
  678.     }
  679.  
  680.     /* fill in this entry */
  681.     current->next = sound_cache_end;
  682.     current->address = address;
  683.     current->length = length;
  684.     current->bits = bits;
  685.     current->frequency = frequency;
  686.  
  687.     /* decode the data into the cache */
  688.     decode_and_filter_cvsd(input, length, bits, frequency, current->data);
  689.     return current->data;
  690. }
  691.  
  692.  
  693. INT16 *find_or_add_to_sound_cache(int address, int length, int bits, int frequency)
  694. {
  695.     sound_cache_entry *current;
  696.  
  697.     for (current = sound_cache; current < sound_cache_end; current = current->next)
  698.         if (current->address == address && current->length == length && current->bits == bits && current->frequency == frequency)
  699.             return current->data;
  700.  
  701.     return add_to_sound_cache(&memory_region(REGION_SOUND1)[address], address, length, bits, frequency);
  702. }
  703.  
  704.  
  705.  
  706. /*************************************
  707.  *
  708.  *    Internal CVSD decoder and player
  709.  *
  710.  *************************************/
  711.  
  712. void play_cvsd(int ch)
  713. {
  714.     sound_channel_data *channel = &sound_channel[ch];
  715.     int address = m6844_channel[ch].address;
  716.     int length = m6844_channel[ch].counter;
  717.     INT16 *base;
  718.  
  719.     /* add the bank number to the address */
  720.     if (exidy440_sound_banks[ch] & 1)
  721.         address += 0x00000;
  722.     else if (exidy440_sound_banks[ch] & 2)
  723.         address += 0x08000;
  724.     else if (exidy440_sound_banks[ch] & 4)
  725.         address += 0x10000;
  726.     else if (exidy440_sound_banks[ch] & 8)
  727.         address += 0x18000;
  728.  
  729.     /* compute the base address in the converted samples array */
  730.     base = find_or_add_to_sound_cache(address, length, channel_bits[ch], channel_frequency[ch]);
  731.     if (!base)
  732.         return;
  733.  
  734.     /* if the length is 0 or 1, just do an immediate end */
  735.     if (length <= 3)
  736.     {
  737.         channel->base = base;
  738.         channel->offset = length;
  739.         channel->remaining = 0;
  740.         m6844_finished(ch);
  741.         return;
  742.     }
  743.  
  744.     if (SOUND_LOG && debuglog)
  745.         fprintf(debuglog, "Sound channel %d play at %02X,%04X, length = %04X, volume = %02X/%02X\n",
  746.                 ch, exidy440_sound_banks[ch], m6844_channel[ch].address,
  747.                 m6844_channel[ch].counter, exidy440_sound_volume[ch * 2], exidy440_sound_volume[ch * 2 + 1]);
  748.  
  749.     /* set the pointer and count */
  750.     channel->base = base;
  751.     channel->offset = 0;
  752.     channel->remaining = length * 8;
  753.  
  754.     /* channels 2 and 3 play twice as slow, so we need to count twice as many samples */
  755.     if (ch & 2) channel->remaining *= 2;
  756. }
  757.  
  758.  
  759. void stop_cvsd(int ch)
  760. {
  761.     /* the DMA channel is marked inactive; that will kill the audio */
  762.     sound_channel[ch].remaining = 0;
  763.     stream_update(sound_stream, 0);
  764.  
  765.     if (SOUND_LOG && debuglog)
  766.         fprintf(debuglog, "Channel %d stop\n", ch);
  767. }
  768.  
  769.  
  770.  
  771. /*************************************
  772.  *
  773.  *    FIR digital filter
  774.  *
  775.  *************************************/
  776.  
  777. void fir_filter(INT32 *input, INT16 *output, int count)
  778. {
  779.     while (count--)
  780.     {
  781.         INT32 result = (input[-1] - input[-8] - input[-48] + input[-55]) << 2;
  782.         result += (input[0] + input[-18] + input[-38] + input[-56]) << 3;
  783.         result += (-input[-2] - input[-4] + input[-5] + input[-51] - input[-52] - input[-54]) << 4;
  784.         result += (-input[-3] - input[-11] - input[-45] - input[-53]) << 5;
  785.         result += (input[-6] + input[-7] - input[-9] - input[-15] - input[-41] - input[-47] + input[-49] + input[-50]) << 6;
  786.         result += (-input[-10] + input[-12] + input[-13] + input[-14] + input[-21] + input[-35] + input[-42] + input[-43] + input[-44] - input[-46]) << 7;
  787.         result += (-input[-16] - input[-17] + input[-19] + input[-37] - input[-39] - input[-40]) << 8;
  788.         result += (input[-20] - input[-22] - input[-24] + input[-25] + input[-31] - input[-32] - input[-34] + input[-36]) << 9;
  789.         result += (-input[-23] - input[-33]) << 10;
  790.         result += (input[-26] + input[-30]) << 11;
  791.         result += (input[-27] + input[-28] + input[-29]) << 12;
  792.         result >>= 14;
  793.  
  794.         if (result < -32768)
  795.             result = -32768;
  796.         else if (result > 32767)
  797.             result = 32767;
  798.  
  799.         *output++ = result;
  800.         input++;
  801.     }
  802. }
  803.  
  804.  
  805.  
  806. /*************************************
  807.  *
  808.  *    CVSD decoder
  809.  *
  810.  *************************************/
  811.  
  812. void decode_and_filter_cvsd(UINT8 *input, int bytes, int maskbits, int frequency, INT16 *output)
  813. {
  814.     INT32 buffer[SAMPLE_BUFFER_LENGTH + FIR_HISTORY_LENGTH];
  815.     int total_samples = bytes * 8;
  816.     int mask = (1 << maskbits) - 1;
  817.     double filter, integrator, leak;
  818.     double charge, decay, gain;
  819.     int steps;
  820.     int chunk_start;
  821.  
  822. #if MAKE_WAVES
  823. {
  824.     static int file_index;
  825.     char file_name[100];
  826.     sprintf(file_name, "cvsd%03d.wav", file_index++);
  827.     wavfile = fopen(file_name, "wb");
  828.     write_wav_header(frequency);
  829. }
  830. #endif
  831.  
  832.     /* compute the charge, decay, and leak constants */
  833.     charge = pow(exp(-1), 1.0 / (FILTER_CHARGE_TC * (double)frequency));
  834.     decay = pow(exp(-1), 1.0 / (FILTER_DECAY_TC * (double)frequency));
  835.     leak = pow(exp(-1), 1.0 / (INTEGRATOR_LEAK_TC * (double)frequency));
  836.  
  837.     /* compute the gain */
  838.     gain = SAMPLE_GAIN;
  839.  
  840.     /* clear the history words for a start */
  841.     memset(&buffer[0], 0, FIR_HISTORY_LENGTH * sizeof(INT32));
  842.  
  843.     /* initialize the CVSD decoder */
  844.     steps = 0xaa;
  845.     filter = FILTER_MIN;
  846.     integrator = 0.0;
  847.  
  848.     /* loop over chunks */
  849.     for (chunk_start = 0; chunk_start < total_samples; chunk_start += SAMPLE_BUFFER_LENGTH)
  850.     {
  851.         INT32 *bufptr = &buffer[FIR_HISTORY_LENGTH];
  852.         int chunk_bytes;
  853.         int ind;
  854.  
  855.         /* how many samples do we generate in this chunk? */
  856.         if (chunk_start + SAMPLE_BUFFER_LENGTH > total_samples)
  857.             chunk_bytes = (total_samples - chunk_start) / 8;
  858.         else
  859.             chunk_bytes = SAMPLE_BUFFER_LENGTH / 8;
  860.  
  861.         /* loop over samples */
  862.         for (ind = 0; ind < chunk_bytes; ind++)
  863.         {
  864.             double temp;
  865.             int databyte = *input++;
  866.             int bit;
  867.             int sample;
  868.  
  869.             /* loop over bits in the byte, low to high */
  870.             for (bit = 0; bit < 8; bit++)
  871.             {
  872.                 /* move the estimator up or down a step based on the bit */
  873.                 if (databyte & (1 << bit))
  874.                 {
  875.                     integrator += filter;
  876.                     steps = (steps << 1) | 1;
  877.                 }
  878.                 else
  879.                 {
  880.                     integrator -= filter;
  881.                     steps <<= 1;
  882.                 }
  883.  
  884.                 /* keep track of the last n bits */
  885.                 steps &= mask;
  886.  
  887.                 /* simulate leakage */
  888.                 integrator *= leak;
  889.  
  890.                 /* if we got all 0's or all 1's in the last n bits, bump the step up */
  891.                 if (steps == 0 || steps == mask)
  892.                 {
  893.                     filter = FILTER_MAX - ((FILTER_MAX - filter) * charge);
  894.                     if (filter > FILTER_MAX)
  895.                         filter = FILTER_MAX;
  896.                 }
  897.  
  898.                 /* simulate decay */
  899.                 else
  900.                 {
  901.                     filter *= decay;
  902.                     if (filter < FILTER_MIN)
  903.                         filter = FILTER_MIN;
  904.                 }
  905.  
  906.                 /* compute the sample as a 32-bit word */
  907.                 temp = integrator * gain;
  908.  
  909.                 /* compress the sample range to fit better in a 16-bit word */
  910.                 if (temp < 0)
  911.                     sample = (int)(temp / (-temp * (1.0 / 32768.0) + 1.0));
  912.                 else
  913.                     sample = (int)(temp / (temp * (1.0 / 32768.0) + 1.0));
  914.  
  915.                 /* store the result to our temporary buffer */
  916.                 *bufptr++ = sample;
  917.             }
  918.         }
  919.  
  920. #if MAKE_WAVES
  921.         for (ind = 0; ind < chunk_bytes * 8; ind++)
  922.         {
  923.             int sample = buffer[FIR_HISTORY_LENGTH + ind];
  924.             INT16 temp;
  925.             if (sample > 32767) sample = 32767;
  926.             else if (sample < -32768) sample = -32768;
  927.             temp = intelShort(sample);
  928.             fwrite(&temp, 1, 2, wavfile);
  929.         }
  930.         wavlength += chunk_bytes * 8 * 2;
  931. #endif
  932.  
  933.         /* all done with this chunk, run the filter on it */
  934.         fir_filter(&buffer[FIR_HISTORY_LENGTH], &output[chunk_start], chunk_bytes * 8);
  935.  
  936.         /* copy the last few input samples down to the start for a new history */
  937.         memcpy(&buffer[0], &buffer[SAMPLE_BUFFER_LENGTH], FIR_HISTORY_LENGTH * sizeof(INT32));
  938.     }
  939.  
  940. #if MAKE_WAVES
  941.     finish_wav_file();
  942.     fclose(wavfile);
  943. #endif
  944.  
  945.     /* make sure the volume goes smoothly to 0 over the last 512 samples */
  946.     if (FADE_TO_ZERO)
  947.     {
  948.         INT16 *data;
  949.  
  950.         chunk_start = (total_samples > 512) ? total_samples - 512 : 0;
  951.         data = output + chunk_start;
  952.         for ( ; chunk_start < total_samples; chunk_start++)
  953.             *data++ = (*data * ((total_samples - chunk_start) >> 9));
  954.     }
  955. }
  956.  
  957.  
  958.  
  959. /*************************************
  960.  *
  961.  *    Debugging
  962.  *
  963.  *************************************/
  964.  
  965. #if MAKE_WAVES
  966.  
  967. static void write_wav_header(int frequency)
  968. {
  969.     UINT32 temp32;
  970.     UINT16 temp16;
  971.  
  972.     fwrite("RIFF", 1, 4, wavfile);
  973.     temp32 = intelLong(0);
  974.     fwrite(&temp32, 1, 4, wavfile);
  975.     fwrite("WAVE", 1, 4, wavfile);
  976.  
  977.     fwrite("fmt ", 1, 4, wavfile);
  978.     temp32 = intelLong(16);
  979.     fwrite(&temp32, 1, 4, wavfile);
  980.     temp16 = intelShort(1);                /* format: PCM */
  981.     fwrite(&temp16, 1, 2, wavfile);
  982.     temp16 = intelShort(1);                /* channels: 1 */
  983.     fwrite(&temp16, 1, 2, wavfile);
  984.     temp32 = intelLong(frequency);        /* sample rate */
  985.     fwrite(&temp32, 1, 4, wavfile);
  986.     temp32 = intelLong(frequency * 2);    /* bytes/second */
  987.     fwrite(&temp32, 1, 4, wavfile);
  988.     temp16 = intelShort(2);                /* block align */
  989.     fwrite(&temp16, 1, 2, wavfile);
  990.     temp16 = intelShort(16);            /* bits/sample */
  991.     fwrite(&temp16, 1, 2, wavfile);
  992.  
  993.     fwrite("data", 1, 4, wavfile);
  994.     temp32 = intelLong(0);
  995.     fwrite(&temp32, 1, 4, wavfile);
  996. }
  997.  
  998.  
  999. static void finish_wav_file(void)
  1000. {
  1001.     UINT32 temp32;
  1002.  
  1003.     fseek(wavfile, 4, SEEK_SET);
  1004.     temp32 = intelLong(wavlength + 4 + 8 + 16 + 8);
  1005.     fwrite(&temp32, 1, 4, wavfile);
  1006.  
  1007.     fseek(wavfile, 40, SEEK_SET);
  1008.     temp32 = intelLong(wavlength);
  1009.     fwrite(&temp32, 1, 4, wavfile);
  1010. }
  1011.  
  1012. #endif
  1013.